package com.dq.health.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dq.health.dao.menu.SysMenuMapper;
import com.dq.health.dao.role.SysRoleMapper;
import com.dq.health.dao.role.SysRoleMenuMapper;
import com.dq.health.dto.response.menu.SysMenuTreeInfo;
import com.dq.health.entity.menu.SysMenu;
import com.dq.health.entity.role.SysRole;
import com.dq.health.entity.role.SysRoleMenu;
import com.dq.health.enums.BaseStatusEnum;
import com.dq.health.service.IAPIMenuService;
import com.dq.health.utils.data.Node;
import com.dq.health.utils.data.Tree;
import com.dq.health.utils.data.TreeUtil;
import com.google.common.collect.Sets;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <>
 *
 * @Author: chenxin
 * @Date: 2021/5/17
 */
@Service
public class MenuServiceImpl implements IAPIMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Override
    public List<SysMenu> selectMenuListByRoleId(Long roleId) {
        List<SysRoleMenu> sysRoleMenus = Optional
            .ofNullable(sysRoleMenuMapper
                .selectList(new QueryWrapper<SysRoleMenu>().lambda().eq(SysRoleMenu::getRoleId, roleId)))
            .orElseGet(ArrayList::new);
        List<SysMenu> sysMenus = new ArrayList<>();
        for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
            sysMenus.add(sysMenuMapper.selectOne(new QueryWrapper<SysMenu>().lambda()
                .eq(SysMenu::getMenuId, sysRoleMenu.getMenuId()).eq(SysMenu::getStatus, true)));
        }
        return sysMenus;
    }

    @Override
    public Tree<SysMenuTreeInfo> buildMenus(List<SysMenu> menus) {
        List<SysMenuTreeInfo> treeInfoList = new LinkedList<>();
        for (SysMenu menu : menus) {
            SysMenuTreeInfo treeInfo = new SysMenuTreeInfo();
            BeanUtils.copyProperties(menu, treeInfo);
            treeInfoList.add(treeInfo);
        }

        Set<Node<SysMenuTreeInfo>> nodes = new LinkedHashSet<>();
        for (SysMenuTreeInfo treeInfo : treeInfoList) {
            Node<SysMenuTreeInfo> node = new Node<>();
            node.setNodeId(treeInfo.getMenuId().toString());
            node.setNodeName(treeInfo.getMenuName());
            node.setIsLeaf(isLeaf(menus, treeInfo.getMenuId()));
            if (treeInfo.getParentId() != null && treeInfo.getParentId() != 0) {
                node.setParentNodeIds(Sets.newHashSet(treeInfo.getParentId().toString()));
            }
            node.setData(treeInfo);
            nodes.add(node);
        }

        return TreeUtil.make(nodes);
    }

    private boolean isLeaf(List<SysMenu> menus, Long menuId) {
        List<SysMenu> collect =
            menus.stream().filter(val -> val.getParentId().equals(menuId)).collect(Collectors.toList());
        return CollectionUtils.isEmpty(collect);

    }

    @Override
    public List<SysMenu> selectMenuList() {
        return sysMenuMapper
            .selectList(new QueryWrapper<SysMenu>().lambda().eq(SysMenu::getStatus, BaseStatusEnum.ENABLED.getValue()));
    }

    @Override
    public SysMenu getMenuByPermission(String permission) {
        SysRole sysRole =
            sysRoleMapper.selectOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleName, permission));
        Long menuId = sysRoleMenuMapper
            .selectOne(new QueryWrapper<SysRoleMenu>().lambda().eq(SysRoleMenu::getRoleId, sysRole.getRoleId()))
            .getMenuId();

        return sysMenuMapper.selectOne(
            new QueryWrapper<SysMenu>().lambda().eq(SysMenu::getMenuId, menuId).eq(SysMenu::getStatus, true));
    }
}
